package com.mldong.mp;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.log.Log;
import com.baomidou.mybatisplus.extension.plugins.handler.DataPermissionHandler;
import com.mldong.annotation.DataScope;
import com.mldong.auth.LoginUser;
import com.mldong.auth.data.DataAuthSqlBuilder;
import com.mldong.auth.data.RoleDataScopeEnum;
import com.mldong.web.LoginUserHolder;
import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
import net.sf.jsqlparser.parser.CCJSqlParserUtil;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

public class DataPermissionHandlerImpl implements DataPermissionHandler {
    private static Log LOG = Log.get();
    private static final Map<String, Class<?>> STATEMENT_ENTITY_MAP = new HashMap<>();
    @Override
    public Expression getSqlSegment(Expression where, String mappedStatementId) {
        try {
            Class<?> mapperClass = getMapperClassFromMappedStatement(mappedStatementId);
            DataScope dataScope = mapperClass.getAnnotation(DataScope.class);
            // 获取方法名
            String methodName = mappedStatementId.substring(mappedStatementId.lastIndexOf(".") + 1);
            // 获取方法对象
            Method method = ReflectUtil.getMethodByName(mapperClass, methodName);
            if(method!=null){
                dataScope = method.getAnnotation(DataScope.class);
            }
            if(dataScope==null){
                return where;
            }
            if(dataScope.ignore()){
                return where;
            }
            LoginUser loginUser = LoginUserHolder.me();
            if(loginUser==null){
                // 当前用户未登录，不进行数据权限控制
                return where;
            }
            if(loginUser.isSuperAdmin()){
                // 当前用户为超级管理员，不进行数据权限控制
                return where;
            }
            if(ObjectUtil.isNotEmpty(loginUser.getRoleDataScopeMap()) && loginUser.getRoleDataScopeMap().containsValue(RoleDataScopeEnum.ALL_DATA)){
                // 当前用户角色数据权限为全部数据权限，不进行数据权限控制
                return where;
            }
            Class<? extends DataAuthSqlBuilder> dataAuthSqlBuilder = dataScope.clazz();
            DataAuthSqlBuilder builder = SpringUtil.getBean(dataAuthSqlBuilder);
            String sqlSegment = builder.build(loginUser, dataScope);
            if(StrUtil.isEmpty(sqlSegment)){
                return where;
            }
            Expression sqlSegmentExpression = CCJSqlParserUtil.parseCondExpression(sqlSegment);
            if (null != where) {
                LOG.info("原 where : " + where.toString());
                return new AndExpression(where, sqlSegmentExpression);
            }
            return sqlSegmentExpression;
        } catch (JSQLParserException e) {
            LOG.error(e);
        }
        return where;
    }

    public static Class<?> getMapperClassFromMappedStatement(String mappedStatementId) {
        return STATEMENT_ENTITY_MAP.computeIfAbsent(mappedStatementId, key -> {
            try {
                String[] parts = key.split("\\.");
                String className = String.join(".", Arrays.asList(parts).subList(0, parts.length - 1));
                Class<?> mapperClass = Class.forName(className);
                return mapperClass;
            } catch (Exception e) {
                throw new RuntimeException("无法解析Mapper类: " + key, e);
            }
        });
    }

}
